﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;

using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Administration;
using System.Globalization;
using System.IO;
using System.Xml;
using System.Data.SqlClient;
using System.Data;
using System.Text;
using Square.Activity;
using System.Reflection;
using System.Configuration;

namespace Square.CONTROLTEMPLATES.Square
{
    public partial class addColleagues : UserControl
    {
        private string _siteUrl { get { return SPContext.Current.Site.Url + "/my"; } }
        private string _webUrl { get { return SPContext.Current.Web.Url; } }
        private string _listUrl { get { return "/my/Lists/Sq_Colleagues"; } }
        private string _listName { get { return "Sq_Colleagues"; } }

        public string _accountName
        {
            get
            {
                if (Request.QueryString["accountname"] != null)
                    return Request.QueryString["accountname"];
                else
                    return this.Page.User.Identity.Name;
            }
        }

        #region protected string DOMAIN_KEY
        /// <summary>
        /// DOMAIN_KEY
        /// </summary>
        /// <returns>Club</returns>
        /// <remarks></remarks>
        protected string DOMAIN_KEY
        {
            get
            {
                string strDomain = ConfigurationManager.AppSettings["WSS_DOMAIN_NAME"];
                return string.IsNullOrEmpty(strDomain) ? "" : strDomain;
            }
        }
        #endregion

        public enum AssociatedGroupTypeEnum { Owners, Members, Vistors };
        public UserProfile _pageUserProfile;
        public UserProfile _colleagueProfile;
        SquareActivityHelper sHelper;
        private bool _EditId { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["LinkID"] != null && !string.IsNullOrEmpty(Request.QueryString["LinkID"]))
                _EditId = true;
        }

        public void lbtn_addColleaguesOk_Click(object sender, EventArgs e)
        {
            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate() 
                {
                    using (SPSite _site = new SPSite(_siteUrl))
                    {
                        using (SPWeb _web = _site.OpenWeb())
                        {
                            SPUserCollection _UserCollection = _web.Users;

                            SPServiceContext context = SPServiceContext.GetContext(_site);
                            UserProfileManager upm = new UserProfileManager(context);

                            if (upm.UserExists(_accountName))
                            {
                                _pageUserProfile = upm.GetUserProfile(_accountName);

                                if (_pageUserProfile != null)
                                {
                                    SPList _list = _web.GetList(_listUrl);
                                    //SPList _list = _web.Lists[_listName];

                                    if (!_EditId)
                                    {
                                        string[] _LinkID = hd_ColleaguesID.Value.Split(',');
                                        // 기존에 다른 그룹에 등록이 되어 있는 동료 인지 확인한다.

                                        foreach (string _id in _LinkID)
                                        {
                                            // DB 저장
                                            db_Save(_id);
                                            // 리스트 저장
                                            _colleagueProfile = upm.GetUserProfile(_id);
                                            bool chkGroup = false;
                                            if (GetColleagueID(_pageUserProfile, _colleagueProfile) != null)
                                                chkGroup = true;
                                            
                                            // 각 아이템의 정보를 받아서 업데이트 한다.
                                            SPListItem _item = _list.Items.Add();
                                            if (chkGroup) _item["Title"] = GetColleagueID(_pageUserProfile, _colleagueProfile).Tables[0].Rows[0]["Id"];              // DB에 저장되는 Id --- DB에는 중복 저장이 되지 않아 없을 수도 있다. 
                                            else _item["Title"] = GetColleagueID(_pageUserProfile, _colleagueProfile).Tables[0].Rows[0]["Id"] + "_" + DateTime.Now.ToString("yyyyMMddhhmmss");  // 없을 경우는 기존 DB에 저장되어 있는 Id_yyyyMMddhhmmss
                                            _item["RecordId"] = _pageUserProfile.RecordId;  // 현재 페이지의 사용자 RecordId
                                            _item["ColleagueRecordId"] = _colleagueProfile.RecordId;                // 동료로 추가되는 RecordId
                                            if (hd_IsGroup.Value == "N")                    // DB에 저장되는 GroupType - 현재 사용되지는 않는다.
                                                _item["GroupType"] = "1";
                                            else
                                                _item["GroupType"] = "0";
                                            _item["GroupTitle"] = string.IsNullOrEmpty(hd_GroupTitle.Value) ? "General" : hd_GroupTitle.Value;      // 선택 박스에서 선택한 그룹 또는 새로 생성된 그룹
                                            _item["IsWorkgroup"] = hd_IsTeam.Value;         // 팀 선택 여부 Y / N
                                            _item["ItemSecurity"] = hd_GroupLevel.Value;    // 공개 설정 여부 1(모두공개) / 2(내동료) / 4(팀공개) / 8(내관리자) / 16(비공개)
                                            _item["PartitionID"] = _pageUserProfile.Suggestions.GetType().GetProperty("PartitionID", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_pageUserProfile.Suggestions, null).ToString(); ;     // SharePoint에서 지정한 PartitionID - 아직 사용되지 않는다.
                                            _item["IsEnable"] = "N";                        // 동료 요청 수락 여부 Y / N - 신규 생성 시 N
                                            _item["IsColleagues"] = hd_IsTeam.Value;        // 팀 그룹 여부 Y / N

                                            _web.AllowUnsafeUpdates = true;
                                            _item.Update();
                                            _web.AllowUnsafeUpdates = false;
                                            
                                            // SPGroup 확인 및 추가
                                            add_SPGroup(_web, _colleagueProfile);

                                            //has been added guest to the room
                                            bool bSave = false;
                                            SquareActivities aType = new SquareActivities();
                                            aType = SquareActivities.SquarePeopleGroupAddPeople;

                                            sHelper = new SquareActivityHelper();
                                            
                                            //bSave = sHelper.SaveActivity(this.Page, aType, rName  + "A가 B를 추가하였습니다.");
                                            string[] strName = _colleagueProfile.DisplayName.Split('\\');
                                            bSave = sHelper.SaveActivity(this.Page, aType, " has added " + "<a href=\"" + _colleagueProfile.PersonalUrl + "\" target=\"_blank\">" + strName[1] + "</a>");
                                        }
                                    }
                                    else
                                    {
                                        string[] _LinkID = Request.QueryString["LinkID"].Split(',');
                                        foreach (string _id in _LinkID)
                                        {
                                            if (!string.IsNullOrEmpty(_id))
                                            {
                                                SPListItem _item = SelectItem(_id, _list);
                                                //리스트 업데이트

                                                if (hd_IsGroup.Value == "N")                    // DB에 저장되는 GroupType - 현재 사용되지는 않는다.
                                                    _item["GroupType"] = "1";
                                                else
                                                    _item["GroupType"] = "0";
                                                _item["GroupTitle"] = string.IsNullOrEmpty(hd_GroupTitle.Value) ? "General" : hd_GroupTitle.Value;      // 선택 박스에서 선택한 그룹 또는 새로 생성된 그룹
                                                _item["IsWorkgroup"] = hd_IsTeam.Value;         // 팀 선택 여부 Y / N
                                                _item["ItemSecurity"] = hd_GroupLevel.Value;    // 공개 설정 여부 1(모두공개) / 2(내동료) / 4(팀공개) / 8(내관리자) / 16(비공개)
                                                _item["IsColleagues"] = hd_IsTeam.Value;        // 팀 그룹 여부 Y / N

                                                _web.AllowUnsafeUpdates = true;
                                                _item.Update();
                                                _web.AllowUnsafeUpdates = false;

                                                add_SPGroup(_web, _colleagueProfile);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                });
            }
            catch {  }

            Page.ClientScript.RegisterStartupScript(this.GetType(), null, "fn_Close();", true);
        }

        public void db_Save(string _id)
        {
            //Open SPSite
            using (SPSite site = new SPSite(_siteUrl))
            {
                //Get Server context
                //SPServiceContext
                SPServiceContext context = SPServiceContext.GetContext(site);
                //ServerContext context = ServerContext.GetContext(site);
                //Get UserProfileManager for the site cocntext
                UserProfileManager profileManager = new UserProfileManager(context);
                UserProfile userProfile;
                if (profileManager.UserExists(_accountName))
                {
                    userProfile = profileManager.GetUserProfile(_accountName);
                    
                    //Check whether the colleague profile exists or not
                    if (profileManager.UserExists(_id))
                    {
                        ColleagueManager colleagueManager;
                        UserProfile colleagueProfile;
                        colleagueProfile = profileManager.GetUserProfile(_id);
                        colleagueManager = userProfile.Colleagues;
                        //Adds collegue with group type peer. This property is marked as public
                        colleagueManager.Create(colleagueProfile, ColleagueGroupType.General, "", false, Privacy.Public);
                    }
                }
            } 
        }

        #region ## 선택 아이템 찾기
        public SPListItem SelectItem(string Title, SPList _list)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<OrderBy>");
            sb.Append("<FieldRef Name=\"Created\" Ascending=\"False\" />");
            sb.Append("</OrderBy>");
            sb.Append("<Where>");
            sb.Append("     <Eq>");
            sb.Append("         <FieldRef Name=\"Title\" />");
            sb.AppendFormat("   <Value Type=\"Text\">{0}</Value>", Title);
            sb.Append("     </Eq>");
            sb.Append("</Where>");

            SPQuery sq = new SPQuery();
            sq.ViewFields = SPQueryViewFields();
            sq.Query = sb.ToString();
            SPListItemCollection _items = _list.GetItems(sq);

            return _items[0];
        }
        #endregion

        #region ## SPQueryViewFields
        public string SPQueryViewFields()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<FieldRef Name=\"Title\" />");
            sb.Append("<FieldRef Name=\"RecordId\" />");
            sb.Append("<FieldRef Name=\"ColleagueRecordId\" />");
            sb.Append("<FieldRef Name=\"IsEnable\" />");
            sb.Append("<FieldRef Name=\"GroupTitle\" />");
            sb.Append("<FieldRef Name=\"GroupType\" />");
            sb.Append("<FieldRef Name=\"IsWorkgroup\" />");
            sb.Append("<FieldRef Name=\"ItemSecurity\" />");
            sb.Append("<FieldRef Name=\"ItemSecurity\" />");
            sb.Append("<FieldRef Name=\"Created\" />");
            return sb.ToString();
        }
        #endregion

        #region ## 해당 동료 가입 여부 확인
        public bool ColleaguesYN(UserProfile pageUserProfile, UserProfile colleagueProfile, SPList _list)
        { 
            bool chk = false;
            StringBuilder sb = new StringBuilder();
            sb.Append("<OrderBy>");
            sb.Append("<FieldRef Name=\"Created\" Ascending=\"False\" />");
            sb.Append("</OrderBy>");
            sb.Append("<Where>");
            sb.Append(" <And>");
            sb.Append("     <Eq>");
            sb.Append("         <FieldRef Name=\"RecordId\" />");
            sb.AppendFormat("   <Value Type=\"Text\">{0}</Value>", pageUserProfile.RecordId);
            sb.Append("     </Eq>");
            sb.Append("     <Eq>");
            sb.Append("         <FieldRef Name=\"ColleagueRecordId\" />");
            sb.AppendFormat("   <Value Type=\"Text\">{0}</Value>", colleagueProfile.RecordId);
            sb.Append("     </Eq>");
            sb.Append(" </And>");
            sb.Append("</Where>");

            SPQuery sq = new SPQuery();
            sq.ViewFields = SPQueryViewFields();
            sq.Query = sb.ToString();
            SPListItemCollection _items = _list.GetItems(sq);
            if (_items.Count <= 0) chk = true;
            return chk;
        }
        #endregion

        #region ## DB Item ID
        public DataSet GetColleagueID(UserProfile userProfile, UserProfile colleagueProfile)
        {
            DataSet ColleagueID = new DataSet();
            SqlDataAdapter adapter;
            StringBuilder ColleagueIDquery = new StringBuilder();

            SqlConnection profileConn = new SqlConnection();
            SqlConnection socialConn = new SqlConnection();
            string partitionid = string.Empty;
            string pConn = string.Empty;
            string sConn = string.Empty;

            if (System.Configuration.ConfigurationManager.ConnectionStrings["ProfileConn"] != null)
            {
                pConn = System.Configuration.ConfigurationManager.ConnectionStrings["ProfileConn"].ToString();
            }
            if (System.Configuration.ConfigurationManager.ConnectionStrings["SocialConn"] != null)
            {
                sConn = System.Configuration.ConfigurationManager.ConnectionStrings["SocialConn"].ToString();
            }

            try
            {
                profileConn.ConnectionString = pConn;
                socialConn.ConnectionString = sConn;
                profileConn.Open();
                socialConn.Open();
            }
            catch (Exception ex)
            {
                if (profileConn != null) profileConn.Dispose();
                if (socialConn != null) socialConn.Dispose();
                throw new Exception(ex.Message);
            }
            //ColleagueID를 가지고 온다
            using (SqlCommand command = new SqlCommand())//new SqlCommand("dbo.proc_SocialComments_GetForUser"))
            {
                partitionid = userProfile.Suggestions.GetType().GetProperty("PartitionID", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(userProfile.Suggestions, null).ToString();

                ColleagueIDquery.AppendLine("SELECT Id");
                ColleagueIDquery.AppendLine(" FROM UserColleagues (NOLOCK)");
                ColleagueIDquery.AppendFormat(" WHERE RecordId = '{0}'", userProfile.RecordId);
                ColleagueIDquery.AppendFormat(" and ColleagueRecordId = '{0}'", colleagueProfile.RecordId);
                //query.AppendLine(" and sc.LastModifiedTime >= @fromDate and sc.LastModifiedTime < @toDate");

                command.CommandText = ColleagueIDquery.ToString();
                command.Connection = profileConn;
                adapter = new SqlDataAdapter();
                adapter.SelectCommand = command;
                adapter.Fill(ColleagueID);

            }
            profileConn.Close();
            if (profileConn != null) profileConn.Dispose();
            socialConn.Close();
            if (socialConn != null) socialConn.Dispose();

            return ColleagueID;
        }
        #endregion

        #region ## SPGroup 생성
        private void add_SPGroup(SPWeb _web, UserProfile _cUser)
        {
            string[] userName = _accountName.Split('\\');

            //Site의 그룹을 가져온다.
            SPGroupCollection groups = _web.SiteGroups;
            
            //권한을 부여할 그룹또는 사용자를 가져온다.
            string spGroupName = string.Empty;
            spGroupName = "FrGroup_" + userName[1];

            SPMember siteOwner = _web.SiteAdministrators[0];
            bool grpExists = false;

            foreach (SPGroup group in groups)
                if (group.Name.ToLower() == spGroupName.ToLower())
                    grpExists = true;

            _web.AllowUnsafeUpdates = true;
            if (!grpExists)
            {
                _web.SiteGroups.Add(spGroupName, siteOwner, null,
                     "Custom Group that I created because I can!");
                _web.Update();

                //get a reference to the group we just created
                SPGroup customGroup = _web.SiteGroups[spGroupName];

                //add the group to the quicklaunch
                _web.Properties["vti_associategroups"] = _web.Properties["vti_associategroups"] + ";" + customGroup.ID.ToString();
                _web.Properties.Update();

                SPUser _colleagueUser = _web.EnsureUser(_cUser.DisplayName);
                customGroup.AddUser(_colleagueUser);

                _web.Update();
            }
            else
            {
                SPGroup _group = _web.SiteGroups[spGroupName];
                SPUser _colleagueUser = _web.EnsureUser(_cUser.DisplayName);
                _group.AddUser(_colleagueUser);
                _web.Update();
            }

            _web.AllowUnsafeUpdates = false;
        }
        
        //spgroup의 멤버들을 삭제
        private void ClearMemberInGroup(string strSPGroupName, SPWeb _cWeb)
        {
            Guid oSiteID = SPContext.Current.Site.ID;
            Guid oWebID = SPContext.Current.Web.ID;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                if (Is_SPGroup_Exist(strSPGroupName, _cWeb))
                {
                    using (SPSite _site = new SPSite(oSiteID))
                    {
                        using (SPWeb _web = _site.OpenWeb(oWebID))
                        {
                            SPGroup SP_WGGroup = _web.SiteGroups[strSPGroupName];

                            foreach (SPUser removeuser in SP_WGGroup.Users)
                            {
                                SP_WGGroup.RemoveUser(removeuser);
                            }
                        }
                    }
                }
            });
        }

        //spgroup에 해당 멤버가 있는지 확인
        private bool Is_SPGroup_Exist(string GroupName, SPWeb _web)
        {
            SPGroupCollection siteGroups = _web.SiteGroups;
            foreach (SPGroup group in siteGroups)
            {
                if (group.Name == GroupName)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Web에 기본 Group를 생성하고, 권한 상속을 제거.
        /// </summary>
        public void CreateGroup(string SiteID, string WebID, string adAdminGroupName, string adMemberGroupName, string AdminGroupPrefix, string MemberGroupPrefix)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite _site = new SPSite(new Guid(SiteID)))
                {
                    using (SPWeb spWeb = _site.OpenWeb(new Guid(WebID)))
                    {
                        string strSpAdminGroupName = AdminGroupPrefix + " Owner";
                        string strSPMemberGroupName = MemberGroupPrefix + "Member";

                        spWeb.AllowUnsafeUpdates = true;

                        //권한 상속 제거
                        spWeb.BreakRoleInheritance(false);

                        //AD그룹을 SPUser 객체에 담아둔다.
                        SPUser adAdminGroup = spWeb.EnsureUser(adAdminGroupName);
                        SPUser adMemberGroup = spWeb.EnsureUser(adMemberGroupName);

                        SPGroupCollection siteGroups = spWeb.SiteGroups;
                        siteGroups.Add(strSpAdminGroupName, _site.Owner, null, "Owner");
                        siteGroups.Add(strSPMemberGroupName, _site.Owner, null, "Member");
                        SPGroup spGroup = spWeb.SiteGroups[strSpAdminGroupName];
                        SPGroup spGroupMember = spWeb.SiteGroups[strSPMemberGroupName];
                        spWeb.AssociatedGroups.Add(spGroup);
                        spWeb.AssociatedGroups.Add(spGroupMember);

                        SPRoleAssignmentCollection roleAssignments = spWeb.RoleAssignments;
                        SPRoleAssignment assignmentEdit = new SPRoleAssignment(spGroup);
                        SPRoleAssignment assignmentEditMember = new SPRoleAssignment(spGroupMember);
                        assignmentEdit.RoleDefinitionBindings.Add(spWeb.RoleDefinitions.GetByType(SPRoleType.Administrator));
                        assignmentEditMember.RoleDefinitionBindings.Add(spWeb.RoleDefinitions.GetByType(SPRoleType.Contributor));
                        roleAssignments.Add(assignmentEdit);
                        roleAssignments.Add(assignmentEditMember);

                        //AD그룹을 SP그룹에 추가 하기.
                        spGroup.AddUser(adAdminGroup);
                        spGroupMember.AddUser(adMemberGroup);

                        spWeb.AllowUnsafeUpdates = false;
                    }
                }

            });


        }

        #endregion
    }
}
